/**
 * Copyright 2007-2010 非也
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.fireflow2.designer.eclipse.properties.datafield;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;

import javax.xml.namespace.QName;

import org.eclipse.gef.editparts.AbstractEditPart;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.fireflow.model.data.Property;
import org.fireflow.model.data.impl.PropertyImpl;
import org.fireflow.pdl.fpdl20.diagram.Fpdl20DiagramElement;
import org.fireflow2.designer.eclipse.Activator;
import org.fireflow2.designer.eclipse.commands.datafield.CreateDataFieldCommand;
import org.fireflow2.designer.eclipse.commands.datafield.DeleteDataFieldCommand;
import org.fireflow2.designer.eclipse.modelwrapper.AbsWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.SubProcessWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.basic.DataFieldWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.collection.DataFieldListWrapper;
import org.fireflow2.designer.eclipse.parts.basic.BasicSubProcessPart;
import org.fireflow2.designer.eclipse.parts.tree.DataFieldListTreePart;

/**
 *
 * @author 非也 nychen2000@163.com
 * Fire Workflow 官方网站：www.firesoa.com 或者 www.fireflow.org
 *
 */
public class DataFieldListPropertySection  extends AbstractPropertySection implements
PropertyChangeListener {
	private static Image addImage = null;
	private static Image deleteImage = null;
	private static Image editImage = null;
	
	private AbstractEditPart editPart = null;
	private DataFieldListWrapper modelWrapper = null;
	private TableViewer dataFieldListTableViewer = null;
	private boolean tableColumnInitialized = false;
	
	public void aboutToBeHidden(){
		super.aboutToBeHidden();
		if (modelWrapper!=null){
			((AbsWrapper)modelWrapper).removePropertyChangeListener(this);
		}
		
	}
	
	public void aboutToBeShown(){
		super.aboutToBeShown();
		if (modelWrapper!=null){
			((AbsWrapper)modelWrapper).addPropertyChangeListener(this);
		}
	}
	public DataFieldListPropertySection(){
		
		ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(Activator.class, "resources/add.png");
		addImage = imageDescriptor.createImage();
		imageDescriptor = ImageDescriptor.createFromFile(Activator.class, "resources/delete.png");
		deleteImage = imageDescriptor.createImage();
		
		imageDescriptor = ImageDescriptor.createFromFile(Activator.class, "resources/property16.png");
		editImage = imageDescriptor.createImage();
	}
	
	public void createControls(final Composite parent,
			TabbedPropertySheetPage aTabbedPropertySheetPage) {
		super.createControls(parent, aTabbedPropertySheetPage);
		
		Composite composite = getWidgetFactory()
				.createComposite(parent);
		composite.setLayout(new GridLayout(3,false));
		
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalAlignment = SWT.RIGHT;
		
		//新增按钮
		Button addButton = getWidgetFactory().createButton(composite, "", SWT.PUSH |SWT.FLAT);
		addButton.setLayoutData(gridData);
		addButton.setImage(addImage);
		addButton.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				CreateDataFieldCommand command = new CreateDataFieldCommand();
				command.setParent(modelWrapper)	;
				editPart.getViewer().getEditDomain().getCommandStack().execute(command);
			}
		});

		//删除按钮
		Button deleteButton = getWidgetFactory().createButton(composite, "", SWT.PUSH);
		deleteButton.setImage(deleteImage);
		deleteButton.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				ISelection selection = dataFieldListTableViewer.getSelection();
				if (selection instanceof StructuredSelection){
					Iterator iterator = ((StructuredSelection)selection).iterator();
					while (iterator.hasNext()){
						Object obj = iterator.next();						
						DeleteDataFieldCommand command = new DeleteDataFieldCommand((DataFieldWrapper)obj);
						editPart.getViewer().getEditDomain().getCommandStack().execute(command);
					}					
				}
			}			
		});
		
		//编辑
		Button editButton =  getWidgetFactory().createButton(composite, "", SWT.PUSH);
		editButton.setImage(editImage);
		editButton.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				ISelection selection = dataFieldListTableViewer.getSelection();
				if (selection instanceof StructuredSelection){
					Object obj = ((StructuredSelection)selection).getFirstElement();
					if (obj!=null){
						editDataField(parent.getShell(),(DataFieldWrapper)obj);
					}

				}
			}
		});
		
		
		//创建属性列表
//		Composite tableContainer = new Composite(composite,SWT.NULL);
		gridData = new GridData(GridData.FILL_BOTH);
		gridData.horizontalSpan = 3;
		gridData.grabExcessVerticalSpace = true;
		gridData.grabExcessHorizontalSpace = true;
		gridData.heightHint = 100;
		gridData.minimumHeight = 50;
//		tableContainer.setLayoutData(gridData);
//		
//		TableColumnLayout tableColumnLayout=new TableColumnLayout(); 
//		tableContainer.setLayout(tableColumnLayout);
//		
		
		dataFieldListTableViewer = new TableViewer(composite, SWT.MULTI | SWT.BORDER
				| SWT.V_SCROLL| SWT.FULL_SELECTION);
		Table table = dataFieldListTableViewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		table.setLayoutData(gridData);

		String[] columnNames = new String[] { "参数名称","中文名","数据类型" ,"初始值" };
		int[] columnAlignments = new int[] { SWT.LEFT,SWT.LEFT, SWT.LEFT,SWT.LEFT};
		for (int i = 0; i < columnNames.length; i++) {
			TableViewerColumn tableColumn = new TableViewerColumn(dataFieldListTableViewer,
					columnAlignments[i]);
			tableColumn.getColumn().setText(columnNames[i]);
			tableColumn.getColumn().setResizable(true);
			tableColumn.getColumn().setMoveable(true);
//			tableColumnLayout.setColumnData(tableColumn, new ColumnWeightData(1, ColumnWeightData.MINIMUM_WIDTH, true));
		}
		
		dataFieldListTableViewer.setContentProvider(new MyTableContentProvider());
		dataFieldListTableViewer.setLabelProvider(new MyTableLabelProvider());
		
		dataFieldListTableViewer.addDoubleClickListener(new IDoubleClickListener(){

			public void doubleClick(DoubleClickEvent event) {
				ISelection selection = event.getSelection();
				if (selection!=null && selection instanceof StructuredSelection){
					Object obj = ((StructuredSelection)selection).getFirstElement();
					if (obj!=null){
						editDataField(parent.getShell(),(DataFieldWrapper)obj);
					}
				}				
			}
			
		});
		
	}
	
	protected void editDataField(Shell shell,DataFieldWrapper oldWrapper){
		//首先赋值DataFieldWrapper
		Property prop = new PropertyImpl();
		Property oldProp = (Property)oldWrapper.getWorkflowModelElement();
		prop.setName(oldProp.getName());
		prop.setDataType(oldProp.getDataType());
		prop.setDataPattern(oldProp.getDataPattern());
		prop.setDescription(oldProp.getDescription());
		prop.setDisplayName(oldProp.getDisplayName());
		prop.setInitialValueAsString(oldProp.getInitialValueAsString());
		prop.setParent(oldProp.getParent());
		
		DataFieldWrapper wrapper = new DataFieldWrapper(prop);
		
		DataFieldEditDialog dialog = new DataFieldEditDialog(shell,wrapper);
		int result = dialog.open();
		if (result==Dialog.OK){
			oldWrapper.setDataType(prop.getDataType());
//			oldWrapper.setDataPattern(prop.getDataPattern());
			oldWrapper.setDescription(prop.getDescription());
			oldWrapper.setDisplayName(prop.getDisplayName());
			oldWrapper.setInitialValue(prop.getInitialValueAsString());
			oldWrapper.setName(prop.getName());
			
			refresh();
		}
	}
	
	public void refresh(){
		dataFieldListTableViewer.setInput(modelWrapper);
        Table table = dataFieldListTableViewer.getTable();   	
    	
    	for( int i = 0; i < table.getColumnCount(); i++ )
    	    table.getColumn(i).pack();

    	dataFieldListTableViewer.refresh();

	}
	public void propertyChange(PropertyChangeEvent evt) {
		// TODO Auto-generated method stub
		if (evt.getPropertyName().equals(Fpdl20DiagramElement.PROPERTY.name()))
			this.refresh();

	}
	@Override
	public void setInput(IWorkbenchPart part, ISelection selection) {
		super.setInput(part, selection);
		Object obj = ((IStructuredSelection) selection).getFirstElement();
		if (obj instanceof DataFieldListTreePart) {
			
			editPart = (AbstractEditPart) obj;
			modelWrapper = (DataFieldListWrapper) editPart.getModel();
		}else if (obj instanceof BasicSubProcessPart){
			editPart = (AbstractEditPart) obj;
			SubProcessWrapper subProcessWrapper = (SubProcessWrapper)editPart.getModel();
			modelWrapper = subProcessWrapper.getDataFieldsWrapper();
		}
	}	
	
	class MyTableContentProvider extends ArrayContentProvider{
	    public Object[] getElements(final Object inputElement) {
	        if (inputElement instanceof DataFieldListWrapper) {
	        	return ((DataFieldListWrapper)inputElement).getChildren().toArray();
			}
	        return new Object[0];
	    }
	}
	
	class MyTableLabelProvider
	   extends LabelProvider
	   implements ITableLabelProvider {
	   public Image getColumnImage(
	      Object element, int index) {
	       return null;
	   }
	   public String getColumnText(Object element, int index) {
	      DataFieldWrapper dataFieldWrapper = (DataFieldWrapper) element;

	      switch (index) {
	         case 0 :
	            return dataFieldWrapper.getName();
	         case 1 :
	        	return dataFieldWrapper.getDisplayName();
	         case 2 :
	            QName dataType = dataFieldWrapper.getDataType();
	            return (dataType==null?"":dataType.toString());
	         case 3 :
	        	 return dataFieldWrapper.getInitialValue();
	         default :
	            return "unknown " + index;
	      }
	   }
	}
	
	class DataFieldEditDialog extends TrayDialog{
		private DataFieldWrapper modelWrapper;
		DataFieldAttributeEditPanel panel = new DataFieldAttributeEditPanel();
		public DataFieldEditDialog(Shell shell,DataFieldWrapper wrapper){
			super(shell);
			modelWrapper = wrapper;
			panel.setModelWrapper(wrapper);
		}
		
		protected Control createDialogArea(Composite parent) {
			Composite container = (Composite) super.createDialogArea(parent);

			FormToolkit formToolkit = new FormToolkit(Display.getCurrent());
			panel.createControl(container, formToolkit);
			panel.refresh();
			return container;
		}
	}
}
